/* Yet Another Forum.net
 * Copyright (C) 2006-2009 Jaben Cargman
 * http://www.yetanotherforum.net/
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text;
using System.Net.Mail;
using System.Web;
using System.Data;

namespace YAF.Classes.Utils
{
	public class YafTemplateEmail
	{

#region Properties

		private string _templateName;

		public string TemplateName
		{
			get { return _templateName; }
			set { _templateName = value; }
		}

		private string _templateLanguageFile;
		public string TemplateLanguageFile
		{
			get
			{
				return _templateLanguageFile;
			}
			set
			{
				_templateLanguageFile = value;
			}
		}

		private bool _htmlEnabled;

		public bool HtmlEnabled
		{
			get	{	return _htmlEnabled; }
			set	{	_htmlEnabled = value;	}
		}

		private StringDictionary _templateParams = new StringDictionary();
		public StringDictionary TemplateParams
		{
			get
			{
				return _templateParams;
			}
			set
			{
				_templateParams = value;
			}
		} 

#endregion
		
		public YafTemplateEmail()
			: this( null, true )
		{

		}
		public YafTemplateEmail( string templateName )
			: this( templateName, true )
		{

		}
		public YafTemplateEmail( string templateName, bool htmlEnabled )
		{
			_templateName = templateName;
			_htmlEnabled = htmlEnabled;
		}

		/// <summary>
		/// Reads a template from the language file
		/// </summary>
		/// <returns>The template</returns>
		private string ReadTemplate(string templateName, string templateLanguageFile)
		{
			if ( !String.IsNullOrEmpty( templateName ) )
			{
				if ( !String.IsNullOrEmpty( templateLanguageFile ))
				{
					YafLocalization localization = new YafLocalization();
					localization.LoadTranslation( templateLanguageFile );
					return localization.GetText( "TEMPLATES", templateName );
				}

				return YafContext.Current.Localization.GetText( "TEMPLATES", templateName );
			}

			return null;
		}

		/// <summary>
		/// Creates an email from a template
		/// </summary>
		/// <returns></returns>
		public string ProcessTemplate(string templateName)
		{
			string email = ReadTemplate( templateName, TemplateLanguageFile );

			if ( !String.IsNullOrEmpty( email ) )
			{
				foreach ( string key in _templateParams.Keys )
				{
					email = email.Replace( key, _templateParams [key] );
				}
			}

			return email;
		}

		public void SendEmail( MailAddress toAddress, string subject, bool useSendThread )
		{
			this.SendEmail( new MailAddress( YafContext.Current.BoardSettings.ForumEmail, YafContext.Current.BoardSettings.Name ), toAddress, subject, useSendThread );
		}

		public void SendEmail( MailAddress fromAddress, MailAddress toAddress, string subject, bool useSendThread)
		{
			string textBody = null, htmlBody = null;

			textBody = ProcessTemplate( TemplateName + "_TEXT" ).Trim();
			htmlBody = ProcessTemplate( TemplateName + "_HTML" ).Trim();

			// null out html if it's not desired
			if ( !HtmlEnabled || String.IsNullOrEmpty( htmlBody ) ) htmlBody = null;

			if ( useSendThread )
			{
				// create this email in the send mail table...
				Data.DB.mail_create( fromAddress.Address, fromAddress.DisplayName, toAddress.Address, toAddress.DisplayName, subject, textBody, htmlBody );
			}
			else
			{
				// just send directly
				SendMail.Send( fromAddress, toAddress, subject, textBody, htmlBody );
			}
		}

		public void CreateWatch( int topicID, int userId, MailAddress fromAddress, string subject )
		{
			string textBody = null, htmlBody = null;

			textBody = ProcessTemplate( TemplateName + "_TEXT" ).Trim();
			htmlBody = ProcessTemplate( TemplateName + "_HTML" ).Trim();

			// null out html if it's not desired
			if ( !HtmlEnabled || String.IsNullOrEmpty( htmlBody ) ) htmlBody = null;

			YAF.Classes.Data.DB.mail_createwatch( topicID, fromAddress.Address, fromAddress.DisplayName, subject, textBody, htmlBody, userId);
		}
	}

	public static class CreateMail
	{
		/// <summary>
		/// Send an error report by email. For this to work, 
		/// smtpserver and erroremail must be set in Web.config.
		/// </summary>
		/// <param name="x">The Exception object to report.</param>
		static public void CreateLogEmail( Exception x )
		{
			try
			{
				string config = YAF.Classes.Config.LogToMail;
				if ( config == null )
					return;

				// Find mail info
				string email = "";
				string server = "";
				string SmtpUserName = "";
				string SmtpPassword = "";

				foreach ( string part in config.Split( ';' ) )
				{
					string [] pair = part.Split( '=' );
					if ( pair.Length != 2 ) continue;

					switch ( pair [0].Trim().ToLower() )
					{
						case "email":
							email = pair [1].Trim();
							break;
						case "server":
							server = pair [1].Trim();
							break;
						case "user":
							SmtpUserName = pair [1].Trim();
							break;
						case "pass":
							SmtpPassword = pair [1].Trim();
							break;
					}
				}

				// Build body
				System.Text.StringBuilder msg = new System.Text.StringBuilder();
				msg.Append( "<style>\r\n" );
				msg.Append( "body,td,th{font:8pt tahoma}\r\n" );
				msg.Append( "table{background-color:#C0C0C0}\r\n" );
				msg.Append( "th{font-weight:bold;text-align:left;background-color:#C0C0C0;padding:4px}\r\n" );
				msg.Append( "td{vertical-align:top;background-color:#FFFBF0;padding:4px}\r\n" );
				msg.Append( "</style>\r\n" );
				msg.Append( "<table cellpadding=1 cellspacing=1>\r\n" );

				if ( x != null )
				{
					msg.Append( "<tr><th colspan=2>Exception</th></tr>" );
					msg.AppendFormat( "<tr><td>Exception</td><td><pre>{0}</pre></td></tr>", x );
					msg.AppendFormat( "<tr><td>Message</td><td>{0}</td></tr>", Text2Html( x.Message ) );
					msg.AppendFormat( "<tr><td>Source</td><td>{0}</td></tr>", Text2Html( x.Source ) );
					msg.AppendFormat( "<tr><td>StackTrace</td><td>{0}</td></tr>", Text2Html( x.StackTrace ) );
					msg.AppendFormat( "<tr><td>TargetSize</td><td>{0}</td></tr>", Text2Html( x.TargetSite.ToString() ) );
				}

				msg.Append( "<tr><th colspan=2>QueryString</th></tr>" );
				foreach ( string key in HttpContext.Current.Request.QueryString.AllKeys )
				{
					msg.AppendFormat( "<tr><td>{0}</td><td>{1}&nbsp;</td></tr>", key, HttpContext.Current.Request.QueryString [key] );
				}
				msg.Append( "<tr><th colspan=2>Form</th></tr>" );
				foreach ( string key in HttpContext.Current.Request.Form.AllKeys )
				{
					msg.AppendFormat( "<tr><td>{0}</td><td>{1}&nbsp;</td></tr>", key, HttpContext.Current.Request.Form [key] );
				}
				msg.Append( "<tr><th colspan=2>ServerVariables</th></tr>" );
				foreach ( string key in HttpContext.Current.Request.ServerVariables.AllKeys )
				{
					msg.AppendFormat( "<tr><td>{0}</td><td>{1}&nbsp;</td></tr>", key, HttpContext.Current.Request.ServerVariables [key] );
				}
				msg.Append( "<tr><th colspan=2>Session</th></tr>" );
				foreach ( string key in HttpContext.Current.Session )
				{
					msg.AppendFormat( "<tr><td>{0}</td><td>{1}&nbsp;</td></tr>", key, HttpContext.Current.Session [key] );
				}
				msg.Append( "<tr><th colspan=2>Application</th></tr>" );
				foreach ( string key in HttpContext.Current.Application )
				{
					msg.AppendFormat( "<tr><td>{0}</td><td>{1}&nbsp;</td></tr>", key, HttpContext.Current.Application [key] );
				}
				msg.Append( "<tr><th colspan=2>Cookies</th></tr>" );
				foreach ( string key in HttpContext.Current.Request.Cookies.AllKeys )
				{
					msg.AppendFormat( "<tr><td>{0}</td><td>{1}&nbsp;</td></tr>", key, HttpContext.Current.Request.Cookies [key].Value );
				}
				msg.Append( "</table>" );

				System.Net.Mail.SmtpClient smtpSend = new System.Net.Mail.SmtpClient( server );

				if ( SmtpUserName.Length > 0 && SmtpPassword.Length > 0 )
				{
					smtpSend.Credentials = new System.Net.NetworkCredential( SmtpUserName, SmtpPassword );
				}

				using ( System.Net.Mail.MailMessage emailMessage = new System.Net.Mail.MailMessage() )
				{
					emailMessage.To.Add( email );
					emailMessage.From = new System.Net.Mail.MailAddress( email );
					emailMessage.Subject = "Yet Another Forum.net Error Report";
					emailMessage.Body = msg.ToString();
					emailMessage.IsBodyHtml = true;

					smtpSend.Send( emailMessage );
				}
			}
			catch ( Exception )
			{
			}
		}

		static public string Text2Html( string html )
		{
			html = html.Replace( "\r\n", "<br/>" );
			html = html.Replace( "\n", "<br/>" );
			return html;
		}

		static public void CreateWatchEmail( object messageID )
		{
			using ( DataTable dt = YAF.Classes.Data.DB.message_list( messageID ) )
			{
				foreach ( DataRow row in dt.Rows )
				{
					int userId = Convert.ToInt32( row["UserID"] );

					YafTemplateEmail watchEmail = new YafTemplateEmail( "TOPICPOST" );

					watchEmail.TemplateLanguageFile = UserHelper.GetUserLanguageFile( userId );

					// Send track mails
					string subject = String.Format( YafContext.Current.Localization.GetText( "COMMON", "TOPIC_NOTIFICATION_SUBJECT" ), YafContext.Current.BoardSettings.Name );

					watchEmail.TemplateParams ["{forumname}"] = YafContext.Current.BoardSettings.Name;
					watchEmail.TemplateParams ["{topic}"] = row ["Topic"].ToString();
					watchEmail.TemplateParams ["{link}"] = String.Format( "{0}{1}", YafForumInfo.ServerURL, YafBuildLink.GetLinkNotEscaped( ForumPages.posts, "m={0}#{0}", messageID ) );

					watchEmail.CreateWatch( Convert.ToInt32( row["TopicID"] ), userId, new MailAddress( YafContext.Current.BoardSettings.ForumEmail, YafContext.Current.BoardSettings.Name ), subject );
				}
			}
		}
	}
}
